package com.ericsson.common.util;

import com.ericsson.enap.modules.kpi.entity.EnipFormula;
import com.ericsson.epc.modules.kpi.entity.Formula;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.googlecode.aviator.Options;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class AviatorUtil {


    public static Map<String,Object> convertFromString(Map<String,String> dataMap){
        Map<String,Object> result = new HashMap<String,Object>();
        for(Map.Entry<String,String> entry : dataMap.entrySet()) {
            if(StringUtils.isBlank(entry.getValue())) {
                result.put(entry.getKey(),Double.valueOf(0));
            } else {
                result.put(entry.getKey(),Double.valueOf(entry.getValue()));
            }
        }
        return result;
    }

    public static Map<String,Object> convertFromDouble(Map<String,Double> dataMap){
        Map<String,Object> result = new HashMap<String,Object>();
        for(Map.Entry<String,Double> entry : dataMap.entrySet()) {
            result.put(entry.getKey(),entry.getValue());
        }
        return result;
    }


    public static Object execute(String expression, Map<String,Object> env){
        AviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
        Expression compiledExp = AviatorEvaluator.compile(expression);
        Object result = 0.0;
        try{
            result = compiledExp.execute(env);
        }catch(Exception e){
            result = 0.0;
        }

        if(result instanceof Double){
            if(((Double) result).isNaN()){
                result = 0.0;
            } else if(((Double) result).isInfinite()) {
                result = -1.0;
            }
            BigDecimal b = new BigDecimal((Double) result);
            result = b.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
        }
        return result;
    }

    public static Object execute(Expression compiledExp, Map<String,Object> env, Formula formula){
        AviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
        Object result = 0.0;
        if(compiledExp != null) {
            try {
                result = compiledExp.execute(env);
            } catch (Exception e) {
                result = 0.0;
            }
        }
        if(result instanceof Double){
            if(((Double) result).isNaN()){
                result = 0.0;
            } else if(((Double) result).isInfinite()) {
                result = -1.0;
            }
            if(formula.getCountertype().equals("0")){
                result = (Double)result * 100;
            }
            BigDecimal b = new BigDecimal((Double) result);
            result = b.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();

        }
        return result;
    }

    public static Object execute(Expression compiledExp, Map<String,Object> env, EnipFormula formula){
        AviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
        Object result = 0.0;
        if(compiledExp != null) {
            try {
                result = compiledExp.execute(env);
            } catch (Exception e) {
                result = 0.0;
            }
        }
        if(result instanceof Double){
            if(((Double) result).isNaN()){
                result = 0.0;
            } else if(((Double) result).isInfinite()) {
                result = -1.0;
            }
            if(formula.getCountertype().equals("0")){
                result = (Double)result * 100;
            }
            BigDecimal b = new BigDecimal((Double) result);
            result = b.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();

        }
        return result;
    }

}
